home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / DISCS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-25  |  12.2 KB  |  698 lines

  1. /****************************************************************************
  2. *                discs.c
  3. *
  4. *  This module implements the disc primitive.
  5. *  This file was written by Alexander Enzmann.  He wrote the code for
  6. *  discs and generously provided us these enhancements.
  7. *
  8. *  from Persistence of Vision(tm) Ray Tracer
  9. *  Copyright 1996 Persistence of Vision Team
  10. *---------------------------------------------------------------------------
  11. *  NOTICE: This source code file is provided so that users may experiment
  12. *  with enhancements to POV-Ray and to port the software to platforms other 
  13. *  than those supported by the POV-Ray Team.  There are strict rules under
  14. *  which you are permitted to use this file.  The rules are in the file
  15. *  named POVLEGAL.DOC which should be distributed with this file. If 
  16. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  17. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  18. *  Forum.  The latest version of POV-Ray may be found there as well.
  19. *
  20. * This program is based on the popular DKB raytracer version 2.12.
  21. * DKBTrace was originally written by David K. Buck.
  22. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  23. *
  24. *****************************************************************************/
  25.  
  26. #include "frame.h"
  27. #include "povray.h"
  28. #include "vector.h"
  29. #include "povproto.h"
  30. #include "bbox.h"
  31. #include "discs.h"
  32. #include "matrices.h"
  33. #include "objects.h"
  34.  
  35.  
  36.  
  37. /*****************************************************************************
  38. * Local preprocessor defines
  39. ******************************************************************************/
  40.  
  41.  
  42.  
  43. /*****************************************************************************
  44. * Static functions
  45. ******************************************************************************/
  46.  
  47. static int Intersect_Disc PARAMS((RAY *Ray, DISC *Disc, DBL *Depth));
  48. static int All_Disc_Intersections PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
  49. static int Inside_Disc PARAMS((VECTOR point, OBJECT *Object));
  50. static void Disc_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  51. static void *Copy_Disc PARAMS((OBJECT *Object));
  52. static void Translate_Disc PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  53. static void Rotate_Disc PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  54. static void Scale_Disc PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  55. static void Transform_Disc PARAMS((OBJECT *Object, TRANSFORM *Trans));
  56. static void Invert_Disc PARAMS((OBJECT *Object));
  57. static void Destroy_Disc PARAMS((OBJECT *Object));
  58. static void Compute_Disc_BBox PARAMS((DISC *Disc));
  59.  
  60. /*****************************************************************************
  61. * Local variables
  62. ******************************************************************************/
  63.  
  64. static METHODS Disc_Methods =
  65. {
  66.   All_Disc_Intersections,
  67.   Inside_Disc, Disc_Normal,
  68.   Copy_Disc, Translate_Disc, Rotate_Disc, Scale_Disc, Transform_Disc,
  69.   Invert_Disc, Destroy_Disc
  70. };
  71.  
  72.  
  73. /*****************************************************************************
  74. *
  75. * FUNCTION
  76. *
  77. *   All_Disc_Intersections
  78. *
  79. * INPUT
  80. *   
  81. * OUTPUT
  82. *   
  83. * RETURNS
  84. *   
  85. * AUTHOR
  86. *
  87. *   Alexander Enzmann
  88. *   
  89. * DESCRIPTION
  90. *
  91. *   -
  92. *
  93. * CHANGES
  94. *
  95. *   -
  96. *
  97. ******************************************************************************/
  98.  
  99. static int All_Disc_Intersections (Object, Ray, Depth_Stack)
  100. OBJECT *Object;
  101. RAY *Ray;
  102. ISTACK *Depth_Stack;
  103. {
  104.   int Intersection_Found;
  105.   DBL Depth;
  106.   VECTOR IPoint;
  107.  
  108.   Intersection_Found = FALSE;
  109.  
  110.   if (Intersect_Disc (Ray, (DISC *)Object, &Depth))
  111.   {
  112.     VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
  113.  
  114.     if (Point_In_Clip (IPoint, Object->Clip))
  115.     {
  116.       push_entry(Depth,IPoint,Object,Depth_Stack);
  117.       Intersection_Found = TRUE;
  118.     }
  119.   }
  120.  
  121.   return (Intersection_Found);
  122. }
  123.  
  124.  
  125.  
  126. /*****************************************************************************
  127. *
  128. * FUNCTION
  129. *
  130. *   Intersect_Disc
  131. *
  132. * INPUT
  133. *
  134. * OUTPUT
  135. *
  136. * RETURNS
  137. *
  138. * AUTHOR
  139. *
  140. *   Alexander Enzmann
  141. *
  142. * DESCRIPTION
  143. *
  144. *   -
  145. *
  146. * CHANGES
  147. *
  148. *   -
  149. *
  150. ******************************************************************************/
  151.  
  152. static int Intersect_Disc (Ray, disc, Depth)
  153. RAY *Ray;
  154. DISC *disc;
  155. DBL *Depth;
  156. {
  157.   DBL t, u, v, r2, len;
  158.   VECTOR P, D;
  159.  
  160.   Increase_Counter(stats[Ray_Disc_Tests]);
  161.  
  162.   /* Transform the point into the discs space */
  163.  
  164.   MInvTransPoint(P, Ray->Initial, disc->Trans);
  165.   MInvTransDirection(D, Ray->Direction, disc->Trans);
  166.  
  167.   VLength(len, D);
  168.   VInverseScaleEq(D, len);
  169.  
  170.   if (fabs(D[Z]) > EPSILON)
  171.   {
  172.     t = -P[Z] / D[Z];
  173.  
  174.     if (t >= 0.0)
  175.     {
  176.       u = P[X] + t * D[X];
  177.       v = P[Y] + t * D[Y];
  178.  
  179.       r2 = Sqr(u) + Sqr(v);
  180.  
  181.       if ((r2 >= disc->iradius2) && (r2 <= disc->oradius2))
  182.       {
  183.         *Depth = t / len;
  184.  
  185.         if ((*Depth > Small_Tolerance) && (*Depth < Max_Distance))
  186.         {
  187.           Increase_Counter(stats[Ray_Disc_Tests_Succeeded]);
  188.  
  189.           return (TRUE);
  190.         }
  191.       }
  192.     }
  193.   }
  194.  
  195.   return (FALSE);
  196. }
  197.  
  198.  
  199.  
  200. /*****************************************************************************
  201. *
  202. * FUNCTION
  203. *
  204. *   Inside_Disc
  205. *
  206. * INPUT
  207. *
  208. * OUTPUT
  209. *
  210. * RETURNS
  211. *
  212. * AUTHOR
  213. *
  214. *   Alexander Enzmann
  215. *
  216. * DESCRIPTION
  217. *
  218. *   -
  219. *
  220. * CHANGES
  221. *
  222. *   -
  223. *
  224. ******************************************************************************/
  225.  
  226. static int Inside_Disc (IPoint, Object)
  227. VECTOR IPoint;
  228. OBJECT *Object;
  229. {
  230.   VECTOR New_Point;
  231.   DISC *disc = (DISC *) Object;
  232.  
  233.   /* Transform the point into the discs space */
  234.  
  235.   MInvTransPoint(New_Point, IPoint, disc->Trans);
  236.  
  237.   if (New_Point[Z] >= 0.0)
  238.   {
  239.     /* We are outside. */
  240.  
  241.     return (Test_Flag(disc, INVERTED_FLAG));
  242.   }
  243.   else
  244.   {
  245.     /* We are inside. */
  246.  
  247.     return (!Test_Flag(disc, INVERTED_FLAG));
  248.   }
  249. }
  250.  
  251.  
  252.  
  253. /*****************************************************************************
  254. *
  255. * FUNCTION
  256. *
  257. *   Disc_Normal
  258. *
  259. * INPUT
  260. *
  261. * OUTPUT
  262. *
  263. * RETURNS
  264. *
  265. * AUTHOR
  266. *
  267. *   Alexander Enzmann
  268. *
  269. * DESCRIPTION
  270. *
  271. *   -
  272. *
  273. * CHANGES
  274. *
  275. *   -
  276. *
  277. ******************************************************************************/
  278.  
  279. static void Disc_Normal (Result, Object, Inter)
  280. OBJECT *Object;
  281. VECTOR Result;
  282. INTERSECTION *Inter;
  283. {
  284.   Assign_Vector(Result, ((DISC *)Object)->normal);
  285. }
  286.  
  287.  
  288.  
  289. /*****************************************************************************
  290. *
  291. * FUNCTION
  292. *
  293. *   Translate_Disc
  294. *
  295. * INPUT
  296. *
  297. * OUTPUT
  298. *
  299. * RETURNS
  300. *
  301. * AUTHOR
  302. *
  303. *   Alexander Enzmann
  304. *
  305. * DESCRIPTION
  306. *
  307. *   -
  308. *
  309. * CHANGES
  310. *
  311. *   -
  312. *
  313. ******************************************************************************/
  314.  
  315. static void Translate_Disc (Object, Vector, Trans)
  316. OBJECT *Object;
  317. VECTOR Vector;
  318. TRANSFORM *Trans;
  319. {
  320.   Transform_Disc(Object, Trans);
  321. }
  322.  
  323.  
  324.  
  325. /*****************************************************************************
  326. *
  327. * FUNCTION
  328. *
  329. *   Rotate_Disc
  330. *
  331. * INPUT
  332. *
  333. * OUTPUT
  334. *
  335. * RETURNS
  336. *
  337. * AUTHOR
  338. *
  339. *   Alexander Enzmann
  340. *
  341. * DESCRIPTION
  342. *
  343. *   -
  344. *
  345. * CHANGES
  346. *
  347. *   -
  348. *
  349. ******************************************************************************/
  350.  
  351. static void Rotate_Disc(Object, Vector, Trans)
  352. OBJECT *Object;
  353. VECTOR Vector;
  354. TRANSFORM *Trans;
  355. {
  356.   MTransNormal(((DISC *)Object)->normal, ((DISC *)Object)->normal, Trans);
  357.  
  358.   Transform_Disc(Object, Trans);
  359. }
  360.  
  361.  
  362.  
  363. /*****************************************************************************
  364. *
  365. * FUNCTION
  366. *
  367. *   Scale_Disc
  368. *
  369. * INPUT
  370. *
  371. * OUTPUT
  372. *
  373. * RETURNS
  374. *
  375. * AUTHOR
  376. *
  377. *   Alexander Enzmann
  378. *
  379. * DESCRIPTION
  380. *
  381. *   -
  382. *
  383. * CHANGES
  384. *
  385. *   -
  386. *
  387. ******************************************************************************/
  388.  
  389. static void Scale_Disc(Object, Vector, Trans)
  390. OBJECT *Object;
  391. VECTOR Vector;
  392. TRANSFORM *Trans;
  393. {
  394.   MTransNormal(((DISC *)Object)->normal, ((DISC *)Object)->normal, Trans);
  395.  
  396.   VNormalize(((DISC *)Object)->normal, ((DISC *)Object)->normal);
  397.  
  398.   Transform_Disc(Object, Trans);
  399. }
  400.  
  401.  
  402.  
  403. /*****************************************************************************
  404. *
  405. * FUNCTION
  406. *
  407. *   Invert_Disc
  408. *
  409. * INPUT
  410. *
  411. * OUTPUT
  412. *
  413. * RETURNS
  414. *
  415. * AUTHOR
  416. *
  417. *   Alexander Enzmann
  418. *
  419. * DESCRIPTION
  420. *
  421. *   -
  422. *
  423. * CHANGES
  424. *
  425. *   -
  426. *
  427. ******************************************************************************/
  428.  
  429. static void Invert_Disc (Object)
  430. OBJECT *Object;
  431. {
  432.   Invert_Flag(Object, INVERTED_FLAG);
  433. }
  434.  
  435.  
  436.  
  437. /*****************************************************************************
  438. *
  439. * FUNCTION
  440. *
  441. *   Transform_Disc
  442. *
  443. * INPUT
  444. *
  445. * OUTPUT
  446. *
  447. * RETURNS
  448. *
  449. * AUTHOR
  450. *
  451. *   Alexander Enzmann
  452. *
  453. * DESCRIPTION
  454. *
  455. *   -
  456. *
  457. * CHANGES
  458. *
  459. *   -
  460. *
  461. ******************************************************************************/
  462.  
  463. static void Transform_Disc (Object, Trans)
  464. OBJECT *Object;
  465. TRANSFORM *Trans;
  466. {
  467.   DISC *Disc = (DISC *)Object;
  468.  
  469.   Compose_Transforms(Disc->Trans, Trans);
  470.  
  471.   /* Recalculate the bounds */
  472.  
  473.   Compute_Disc_BBox(Disc);
  474. }
  475.  
  476.  
  477.  
  478. /*****************************************************************************
  479. *
  480. * FUNCTION
  481. *
  482. *   Create_Disc
  483. *
  484. * INPUT
  485. *
  486. * OUTPUT
  487. *
  488. * RETURNS
  489. *
  490. * AUTHOR
  491. *
  492. *   Alexander Enzmann
  493. *
  494. * DESCRIPTION
  495. *
  496. *   -
  497. *
  498. * CHANGES
  499. *
  500. *   -
  501. *
  502. ******************************************************************************/
  503.  
  504. DISC *Create_Disc ()
  505. {
  506.   DISC *New;
  507.  
  508.   New = (DISC *)POV_MALLOC(sizeof (DISC), "disc");
  509.  
  510.   INIT_OBJECT_FIELDS(New, DISC_OBJECT, &Disc_Methods)
  511.  
  512.   Make_Vector (New->center, 0.0, 0.0, 0.0);
  513.   Make_Vector (New->normal, 0.0, 0.0, 1.0);
  514.  
  515.   New->iradius2 = 0.0;
  516.   New->oradius2 = 1.0;
  517.  
  518.   New->d = 0.0;
  519.  
  520.   New->Trans = Create_Transform();
  521.  
  522.   /* Default bounds */
  523.  
  524.   Make_BBox(New->BBox, -1.0, -1.0, -Small_Tolerance, 2.0,  2.0, 2.0 * Small_Tolerance);
  525.  
  526.   return (New);
  527. }
  528.  
  529.  
  530.  
  531. /*****************************************************************************
  532. *
  533. * FUNCTION
  534. *
  535. *   Copy_Disc
  536. *
  537. * INPUT
  538. *
  539. * OUTPUT
  540. *
  541. * RETURNS
  542. *
  543. * AUTHOR
  544. *
  545. *   Alexander Enzmann
  546. *
  547. * DESCRIPTION
  548. *
  549. *   -
  550. *
  551. * CHANGES
  552. *
  553. *   Sep 1994 : Fixed memory leakage [DB]
  554. *
  555. ******************************************************************************/
  556.  
  557. static void *Copy_Disc (Object)
  558. OBJECT *Object;
  559. {
  560.   DISC *New;
  561.  
  562.   New  = Create_Disc();
  563.  
  564.   /* Get rid of the transformation created in Create_Disc(). */
  565.  
  566.   Destroy_Transform(New->Trans);
  567.  
  568.   /* Copy disc. */
  569.  
  570.   *New = *((DISC *) Object);
  571.  
  572.   New->Trans = Copy_Transform(((DISC *)Object)->Trans);
  573.  
  574.   return (New);
  575. }
  576.  
  577.  
  578.  
  579. /*****************************************************************************
  580. *
  581. * FUNCTION
  582. *
  583. *   Destroy_Disc
  584. *
  585. * INPUT
  586. *
  587. * OUTPUT
  588. *
  589. * RETURNS
  590. *
  591. * AUTHOR
  592. *
  593. *   Alexander Enzmann
  594. *
  595. * DESCRIPTION
  596. *
  597. *   -
  598. *
  599. * CHANGES
  600. *
  601. *   -
  602. *
  603. ******************************************************************************/
  604.  
  605. static void Destroy_Disc (Object)
  606. OBJECT *Object;
  607. {
  608.   Destroy_Transform(((DISC *)Object)->Trans);
  609.  
  610.   POV_FREE (Object);
  611. }
  612.  
  613.  
  614.  
  615. /*****************************************************************************
  616. *
  617. * FUNCTION
  618. *
  619. *   Compute_Disc
  620. *
  621. * INPUT
  622. *
  623. *   Disc - Disc
  624. *
  625. * OUTPUT
  626. *
  627. *   Disc
  628. *
  629. * RETURNS
  630. *
  631. * AUTHOR
  632. *
  633. *   Dieter Bayer
  634. *
  635. * DESCRIPTION
  636. *
  637. *   Calculate the transformation that scales, rotates, and translates
  638. *   the disc to the desired location and orientation.
  639. *
  640. * CHANGES
  641. *
  642. *   Aug 1994 : Creation.
  643. *
  644. ******************************************************************************/
  645.  
  646. void Compute_Disc(Disc)
  647. DISC *Disc;
  648. {
  649.   Compute_Coordinate_Transform(Disc->Trans, Disc->center, Disc->normal, 1.0, 1.0);
  650.  
  651.   Compute_Disc_BBox(Disc);
  652. }
  653.  
  654.  
  655.  
  656. /*****************************************************************************
  657. *
  658. * FUNCTION
  659. *
  660. *   Compute_Disc_BBox
  661. *
  662. * INPUT
  663. *
  664. *   Disc - Disc
  665. *
  666. * OUTPUT
  667. *
  668. *   Disc
  669. *
  670. * RETURNS
  671. *
  672. * AUTHOR
  673. *
  674. *   Dieter Bayer
  675. *
  676. * DESCRIPTION
  677. *
  678. *   Calculate the bounding box of a disc.
  679. *
  680. * CHANGES
  681. *
  682. *   Aug 1994 : Creation.
  683. *
  684. ******************************************************************************/
  685.  
  686. static void Compute_Disc_BBox(Disc)
  687. DISC *Disc;
  688. {
  689.   DBL rad;
  690.  
  691.   rad = sqrt(Disc->oradius2);
  692.  
  693.   Make_BBox(Disc->BBox, -rad, -rad, -Small_Tolerance, 2.0*rad, 2.0*rad, 2.0*Small_Tolerance);
  694.  
  695.   Recompute_BBox(&Disc->BBox, Disc->Trans);
  696. }
  697.  
  698.